home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / metkit / myio.cpp < prev    next >
C/C++ Source or Header  |  1997-06-07  |  5KB  |  169 lines

  1. //    Copyright (C) 1996, 1997 Meta Four Software.  All rights reserved.
  2. //
  3. //  This code demonstrates:
  4. //
  5. //      - A class derived from c4_Strategy to implement encrypted storage.
  6. //      - Disabling the Flush calls issued during Commit() for speed.
  7. //      - Using c4_Strategy objects as the basis of all file I/O in MetaKit.
  8. //
  9. //! rev="$Id: myio.cpp,v 1.6 1997/05/27 00:06:46 jcw Rel $"
  10.  
  11. #include "m4kit.h"
  12. #include "k4strat.h"
  13.  
  14. #include <stdio.h>
  15. #include <string.h>
  16.  
  17. #ifdef macintosh
  18.     #include <assert.h>
  19.     #define ASSERT assert
  20. #endif  
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // A helper class which owns a temporary buffer
  24.  
  25. class CTempBuffer
  26. {
  27. public:
  28.     CTempBuffer (int len_) : _buf (new char [len_]) { }
  29.     ~CTempBuffer () { delete [] _buf; }
  30.  
  31.     operator void* () const { return _buf; }
  32.     char& operator[] (int i) { return _buf[i]; }
  33.  
  34. private:
  35.     char* _buf;
  36. };
  37.  
  38. /////////////////////////////////////////////////////////////////////////////
  39. // This derived strategy encrypts its data on disk and omits flushes
  40.  
  41. class CEncryptStrategy : public c4_Strategy
  42. {
  43. public:
  44.     CEncryptStrategy ()
  45.         : _pos (0) { }
  46.     virtual ~CEncryptStrategy ()
  47.         { /* nothing */ }
  48.  
  49.         // Need to track the file position to implement better encryption
  50.     virtual void DataSeek(long lOff)
  51.         { _pos = lOff; c4_Strategy::DataSeek(lOff); }
  52.  
  53.         // Reading and writing of course messes around with all the data
  54.     virtual int  DataRead(void*, int);
  55.     virtual void DataWrite(const void*, int);
  56.  
  57.         // For this example, we also disable all explicit file flushes
  58.     virtual void DataCommit(long)
  59.         { }
  60.  
  61. private:
  62.         // This example uses a trivial encoding.  The important aspect to
  63.         // consider is to make sure that seeks do not mess up the encoding.
  64.         // But as shown below, the offset of the data CAN be incorporated.
  65.     inline char Encode(char c_) const
  66.         { return (char) (c_ ^ _pos ^ 211); }
  67.     inline char Decode(char c_) const
  68.         { return (char) (c_ ^ _pos ^ 211); }
  69.  
  70.     long _pos;
  71. };
  72.  
  73. int CEncryptStrategy::DataRead(void* lpBuf, int nCount)
  74. {
  75.     int result = 0;
  76.  
  77.     if (nCount > 0)
  78.     {
  79.         CTempBuffer buf (nCount);
  80.         char* dest = (char*) lpBuf;
  81.  
  82.         result = c4_Strategy::DataRead(buf, nCount);
  83.  
  84.         for (int i = 0; i < result; ++i)
  85.         {
  86.             dest[i] = Decode(buf[i]);
  87.             ++_pos;
  88.         }
  89.     }
  90.  
  91.     return result;
  92. }
  93.  
  94. void CEncryptStrategy::DataWrite(const void* lpBuf, int nCount)
  95. {
  96.     if (nCount > 0)
  97.     {
  98.         CTempBuffer buf (nCount);
  99.         const char* src = (const char*) lpBuf;
  100.  
  101.         memcpy(buf, lpBuf, nCount);
  102.  
  103.         for (int i = 0; i < nCount; ++i)
  104.         {
  105.             buf[i] = Encode(src[i]);
  106.             ++_pos;
  107.         }
  108.  
  109.         c4_Strategy::DataWrite(buf, nCount);
  110.     }
  111. }
  112.  
  113. /////////////////////////////////////////////////////////////////////////////
  114.  
  115. int main()
  116. {
  117.         // This property could just as well have been declared globally.
  118.     c4_StringProp pLine ("line");
  119.  
  120.     {
  121.             // This is where the magic takes place.
  122.         CEncryptStrategy efile;
  123.         efile.DataOpen("secret.dat", true);
  124.         
  125.         c4_Storage storage (efile);
  126.  
  127.         static const char* message[] = {
  128.             "This is a small message which will be encrypted on file.",
  129.             "As a result, none of the other MetaKit utilities can read it.",
  130.             "Furthermore, a hex dump of this file will produce gibberish.",
  131.             "The encryption used here is ridiculously simple, however.",
  132.             "Beware of naive encryption schemes, cracking them is a sport.",
  133.             0
  134.         };
  135.  
  136.             // Store the text lines as separate entries in the view.
  137.         c4_View vText;
  138.  
  139.         for (const char** p = message; *p; ++p)
  140.             vText.Add(pLine [*p]);
  141.  
  142.         storage.Store("text", vText);
  143.         storage.Commit();
  144.     }
  145.  
  146.         // The end of the preceding block will flush out all data to file.
  147.  
  148.     {
  149.             // Repeat the process when accessing the encrypted file again.
  150.         CEncryptStrategy efile;
  151.         efile.DataOpen("secret.dat", false);
  152.  
  153.         c4_Storage storage (efile);
  154.         c4_View vText = storage.View("text");
  155.  
  156.         for (int i = 0; i < vText.GetSize(); ++i)
  157.         {
  158.             c4_String s = pLine (vText[i]);
  159.             puts(s);
  160.         }
  161.     }
  162.  
  163.         // At this point, an encrypted data file is left behind on the disk.
  164.  
  165.     return 0;
  166. }
  167.  
  168. /////////////////////////////////////////////////////////////////////////////
  169.